package com.tanhua.dubbo.api.mongo;

import com.google.errorprone.annotations.Var;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.UserLike;
import com.tanhua.domain.mongo.UserLocation;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.UserLocationVo;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metric;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.BooleanOperators;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;


@Service
public class RecommendUserApiImpl implements RecommendUserApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public RecommendUser todayBest(Long loginId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("toUserId").is(loginId));
        query.with(Sort.by(Sort.Order.desc("score")));
        RecommendUser todayBest = mongoTemplate.findOne(query, RecommendUser.class);
        return todayBest;
    }

    @Override
    public PageResult findPage(Long loginId, Integer page, Integer pagesize) {
        Query query = new Query(Criteria.where("toUserId").is(loginId));
        long total = mongoTemplate.count(query, RecommendUser.class);
        List<RecommendUser> recommendList = new ArrayList<>();
        if (total > 0) {
            query.skip((page - 1) * pagesize).limit(pagesize);
            recommendList = mongoTemplate.find(query, RecommendUser.class);
        }
        PageResult pageResult = new PageResult();
        pageResult.setItems(recommendList);
        pageResult.setCounts(total);
        pageResult.setPages(total / pagesize + (total % pagesize > 0 ? 1 : 0));
        pageResult.setPage(Long.valueOf(page));
        return pageResult;
    }

    @Override
    public RecommendUser findUserById(String personId, Long longInUserId) {
        Query query = new Query(Criteria.where("userId").is(personId).and("toUserId").is(longInUserId));
        RecommendUser user = mongoTemplate.findOne(query, RecommendUser.class);
        return user;
    }

    @Override
    public List<UserLocationVo> search(Long userId, Long distance) {
        List<UserLocationVo> userLocationVos = new ArrayList<>();
        Query query = new Query(Criteria.where("userId").is(userId));
        UserLocation location = mongoTemplate.findOne(query, UserLocation.class);
        if (null == location) {
            return userLocationVos;
        }

        GeoJsonPoint point = location.getLocation();
        Distance redius = new Distance(distance / 1000, Metrics.KILOMETERS);
        Circle circle = new Circle(point, redius);
        query = new Query(Criteria.where("location").withinSphere(circle).and("useId").ne(userId));
        List<UserLocation> userLocations = mongoTemplate.find(query, UserLocation.class);
        return UserLocationVo.formatToList(userLocations);
    }

    @Override
    public void loveUser(Long recommendId, Long userId) {
        Query query = new Query(Criteria.where("userId").is(userId).and("likeUserId").is(recommendId));
        if (!mongoTemplate.exists(query, UserLike.class)) {
            UserLike userLike = new UserLike();
            userLike.setCreated(System.currentTimeMillis());
            userLike.setLikeUserId(Long.valueOf(recommendId));
            userLike.setUserId(userId);
            mongoTemplate.insert(userLike);
        }
    }

    @Override
    public void unloveUser(Long recommendId, Long userId) {
        Query query = new Query(Criteria.where("userId").is(userId).and("likeUserId").is(recommendId));
        DeleteResult remove = mongoTemplate.remove(query, UserLike.class);
    }
}
